home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1997 #1 / Amiga Plus CD - 1997 - No. 01.iso / pd / programmierung / mesa-1.2.8 / widgets / demos / cube.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  8KB  |  332 lines

  1. /* demo.c -- Demo program for the Mesa widget
  2.    Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2 of the License, or
  7.    (at your option) any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; see the file COPYING.  If not, write to
  16.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.    $Id: cube.c,v 1.14 1995/05/19 20:30:57 ohl Exp $
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <stdarg.h>
  24. #include <math.h>
  25. #include <X11/X.h>
  26. #include <X11/Intrinsic.h>
  27. #include <X11/StringDefs.h>
  28. #include <X11/Shell.h>
  29. #include <X11/Xaw/Command.h>
  30. #include <X11/Xaw/Form.h>
  31. #include <GL/xmesa.h>
  32. #include <GL/gl.h>
  33. #include <GL/GLwDrawA.h>
  34.  
  35. static char *RCS_Id =
  36. "@(#) $Id: cube.c,v 1.14 1995/05/19 20:30:57 ohl Exp $";
  37.  
  38. static GLint Black, Red, Green, Blue;
  39.  
  40. void quit_function (Widget, XtPointer, XtPointer);
  41.  
  42. void
  43. quit_function (Widget w, XtPointer closure, XtPointer call_data)
  44. {
  45.   exit (0);
  46. }
  47.  
  48. static void
  49. draw_cube (void)
  50. {
  51.   /* X faces */
  52.   glIndexi (Red);
  53.   glColor3f (1.0, 0.0, 0.0);
  54.   glBegin (GL_POLYGON);
  55.   {
  56.     glVertex3f (1.0, 1.0, 1.0);
  57.     glVertex3f (1.0, -1.0, 1.0);
  58.     glVertex3f (1.0, -1.0, -1.0);
  59.     glVertex3f (1.0, 1.0, -1.0);
  60.   }
  61.   glEnd ();
  62.  
  63.   glBegin (GL_POLYGON);
  64.   {
  65.     glVertex3f (-1.0, 1.0, 1.0);
  66.     glVertex3f (-1.0, 1.0, -1.0);
  67.     glVertex3f (-1.0, -1.0, -1.0);
  68.     glVertex3f (-1.0, -1.0, 1.0);
  69.   }
  70.   glEnd ();
  71.  
  72.   /* Y faces */
  73.   glIndexi (Green);
  74.   glColor3f (0.0, 1.0, 0.0);
  75.   glBegin (GL_POLYGON);
  76.   {
  77.     glVertex3f (1.0, 1.0, 1.0);
  78.     glVertex3f (1.0, 1.0, -1.0);
  79.     glVertex3f (-1.0, 1.0, -1.0);
  80.     glVertex3f (-1.0, 1.0, 1.0);
  81.   }
  82.   glEnd ();
  83.  
  84.   glBegin (GL_POLYGON);
  85.   {
  86.     glVertex3f (1.0, -1.0, 1.0);
  87.     glVertex3f (-1.0, -1.0, 1.0);
  88.     glVertex3f (-1.0, -1.0, -1.0);
  89.     glVertex3f (1.0, -1.0, -1.0);
  90.   }
  91.   glEnd ();
  92.  
  93.   /* Z faces */
  94.   glIndexi (Blue);
  95.   glColor3f (0.0, 0.0, 1.0);
  96.   glBegin (GL_POLYGON);
  97.   {
  98.     glVertex3f (1.0, 1.0, 1.0);
  99.     glVertex3f (-1.0, 1.0, 1.0);
  100.     glVertex3f (-1.0, -1.0, 1.0);
  101.     glVertex3f (1.0, -1.0, 1.0);
  102.   }
  103.   glEnd ();
  104.  
  105.   glBegin (GL_POLYGON);
  106.   {
  107.     glVertex3f (1.0, 1.0, -1.0);
  108.     glVertex3f (1.0, -1.0, -1.0);
  109.     glVertex3f (-1.0, -1.0, -1.0);
  110.     glVertex3f (-1.0, 1.0, -1.0);
  111.   }
  112.   glEnd ();
  113. }
  114.  
  115. GLfloat xrot, yrot, zrot;
  116.  
  117. static void
  118. init_display (Widget w)
  119. {
  120.   xrot = yrot = zrot = 0.0;
  121.  
  122.   glClearColor (0.0, 0.0, 0.0, 0.0);
  123.   glClearIndex (Black);
  124.   glClearDepth (10.0);
  125.  
  126.   glMatrixMode (GL_PROJECTION);
  127.   glLoadIdentity ();
  128.   glFrustum (-1.0, 1.0, -1.0, 1.0, 1.0, 10.0);
  129.   glTranslatef (0.0, 0.0, -3.0);
  130.  
  131.   glMatrixMode (GL_MODELVIEW);
  132.   glLoadIdentity ();
  133.  
  134.   glCullFace (GL_BACK);
  135.   glEnable (GL_CULL_FACE);
  136.  
  137.   glShadeModel (GL_FLAT);
  138. }
  139.  
  140. static void
  141. display (Widget w)
  142. {
  143.   glClear (GL_COLOR_BUFFER_BIT);
  144.   glPushMatrix ();
  145.   {
  146.     glRotatef (xrot, 1.0, 0.0, 0.0);
  147.     glRotatef (yrot, 0.0, 1.0, 0.0);
  148.     glRotatef (zrot, 0.0, 0.0, 1.0);
  149.     draw_cube ();
  150.   }
  151.   glPopMatrix ();
  152.   glFinish ();
  153.   XMesaSwapBuffers ();
  154.       
  155.   xrot += 1.0;
  156.   yrot += 0.7;
  157.   zrot -= 0.3;
  158. }
  159.  
  160.  
  161. static GLint
  162. alloc_color (Widget w, Colormap cmap, int red, int green, int blue)
  163.   XColor xcolor;
  164.   xcolor.red = red;
  165.   xcolor.green = green;
  166.   xcolor.blue = blue;
  167.   xcolor.flags = DoRed | DoGreen | DoBlue;
  168.   if (!XAllocColor (XtDisplay (w), cmap, &xcolor))
  169.     {
  170.       printf ("Couldn't allocate color!\n");
  171.       exit (1);
  172.     }
  173.   return xcolor.pixel;
  174. }
  175.  
  176. /* This is rather inefficient, but we don't mind for the moment,
  177.    because it works.  */
  178.  
  179. static void
  180. translate_pixels (Widget to, Widget from, ...)
  181. {
  182.   va_list ap;
  183.   char *name;
  184.   Colormap from_cmap, to_cmap;
  185.   XColor xcolor;
  186.  
  187.   XtVaGetValues (from, XtNcolormap, &from_cmap, NULL);
  188.   XtVaGetValues (to, XtNcolormap, &to_cmap, NULL);
  189.  
  190.   va_start (ap, from);
  191.   for (name = va_arg (ap, char *); name != NULL; name = va_arg (ap, char *))
  192.     {
  193.       XtVaGetValues (from, name, &xcolor.pixel, NULL);
  194.       XQueryColor (XtDisplay (from), from_cmap, &xcolor);
  195.       if (!XAllocColor (XtDisplay (to), to_cmap, &xcolor))
  196.     XtAppWarning (XtWidgetToApplicationContext (to),
  197.               "Couldn't allocate color!\n");
  198.       else
  199.     XtVaSetValues (from, name, xcolor.pixel, NULL);
  200.     }
  201.   va_end (ap);
  202. }
  203.  
  204. /* Just like the movies: do 24 frames per second. */
  205. unsigned long delay = 1000/24;
  206.  
  207. static void first_frame (Widget);
  208. static void next_frame (XtPointer, XtIntervalId *);
  209.  
  210. static void
  211. first_frame (Widget w)
  212. {
  213.   XtAppAddTimeOut (XtWidgetToApplicationContext (w),
  214.               delay, next_frame, (XtPointer) w);
  215. }
  216.  
  217. static void
  218. next_frame (XtPointer client_data, XtIntervalId *id)
  219. {
  220.   Widget w = (Widget) client_data;
  221.   first_frame (w);
  222.   display (w);
  223. }
  224.  
  225. static String fallback_resources[] =
  226. {
  227.   "*GLwDrawingArea.width: 300",
  228.   "*GLwDrawingArea.height: 300",
  229.   "*GLwDrawingArea.rgba: true",
  230.   "*GLwDrawingArea.installColormap: true",
  231.   "*GLwDrawingArea.doublebuffer: true",
  232.   NULL
  233. };
  234.  
  235. int
  236. main (int argc, char *argv[])
  237. {
  238.   Widget top, frame, mesa, quit;
  239.   XtAppContext app_context;
  240.   GLXContext glx_context;
  241.   XVisualInfo *vi;
  242.   Boolean rgba, doublebuffer, cmap_installed;
  243.  
  244.   top = XtVaAppInitialize (&app_context, "Cube",
  245.                NULL, 0,
  246.                &argc, argv, fallback_resources,
  247.                NULL);
  248.  
  249.   frame = XtVaCreateManagedWidget ("frame", formWidgetClass,
  250.                    top,
  251.                    NULL);
  252.   mesa = XtVaCreateManagedWidget ("mesa", glwDrawingAreaWidgetClass,
  253.                   frame,
  254.                   NULL);
  255.   quit = XtVaCreateManagedWidget ("quit", commandWidgetClass,
  256.                   frame,
  257.                                   XtNfromHoriz, mesa, XtNhorizDistance, 10,
  258.                   NULL);
  259.   XtAddCallback (quit, XtNcallback, quit_function, NULL);
  260.  
  261.   XtRealizeWidget (top);
  262.  
  263.   XtVaGetValues (mesa,
  264.          GLwNrgba, &rgba,
  265.          GLwNinstallColormap, &cmap_installed,
  266.          GLwNdoublebuffer, &doublebuffer,
  267.          GLwNvisualInfo, &vi, NULL);
  268.  
  269.   /* create a visual context */
  270. #ifdef XMESA_H
  271.   /* This simple example burns _a_lot_ less CPU cycles if the double
  272.      buffering utilizes a pixmap.  glXCreateContext() forces us to use
  273.      an Ximage.  Therefore it is faster (though not portable) to use
  274.      XMesaCreateContext() explicitely.  */
  275.   glx_context = XMesaCreateContext (XtDisplay (mesa), vi,
  276.                     (GLboolean) rgba,
  277.                                     GL_FALSE,  /* alpha */
  278.                     (GLboolean) doublebuffer,
  279.                                     1, /* depth size */
  280.                                     0, /* stencil size */
  281.                                     0, /* accum size */
  282.                     GL_FALSE, /* ximage flag */
  283.                                     NULL);
  284.   XMesaBindWindow (glx_context, XtWindow (mesa));
  285. #else /* not Mesa */
  286.   glx_context = glXCreateContext (XtDisplay(mesa), vi, 0, GL_FALSE);
  287. #endif /* not Mesa */
  288.  
  289.   GLwDrawingAreaMakeCurrent (mesa, glx_context);
  290.  
  291.   if (rgba)
  292.     {
  293.       Black = Red = Green = Blue = 0;
  294.  
  295.       if (cmap_installed)
  296.     {
  297.       /* In RGBA mode, the Mesa widgets will have their own color map.
  298.          Adjust the colors of the other widgets so that--even if the rest
  299.          of the screen has wrong colors--all application widgets have the
  300.          right colors.  */
  301.              
  302.       translate_pixels (mesa, quit,
  303.                 XtNbackground, XtNforeground, XtNborder, NULL);
  304.       translate_pixels (mesa, frame, XtNbackground, XtNborder, NULL);
  305.  
  306.       /* Finally warp the pointer into the mesa widget, to make sure that
  307.          the user sees the right colors at the beginning.  */
  308.  
  309.       XWarpPointer (XtDisplay (mesa), None, XtWindow (mesa),
  310.             0, 0, 0, 0, 0, 0);
  311.     }
  312.     }
  313.   else
  314.     {
  315.       /* Allocate a few colors for use in color index mode.  */
  316.  
  317.       Colormap cmap;
  318.       cmap = DefaultColormap (XtDisplay (top), DefaultScreen (XtDisplay (top)));
  319.       Black = alloc_color (top, cmap, 0x0000, 0x0000, 0x0000);
  320.       Red   = alloc_color (top, cmap, 0xffff, 0x0000, 0x0000);
  321.       Green = alloc_color (top, cmap, 0x0000, 0xffff, 0x0000);
  322.       Blue  = alloc_color (top, cmap, 0x0000, 0x0000, 0xffff);
  323.     }
  324.  
  325.   init_display (mesa);
  326.   first_frame (mesa);
  327.  
  328.   XtAppMainLoop (app_context);
  329.   return (0);
  330. }
  331.